from google.appengine.ext import db
from google.appengine.ext.db import polymodel
from google.appengine.api import users


class UserProfile(db.Expando):
    user = db.UserProperty(required=True)
    
    @classmethod
    def get_by_user(cls, user):
        if user is None:
          return None
        email = user.email()
        assert email
        key = '<%s>' % email
        return cls.get_or_insert(key, user=user)
    
    @classmethod
    def get_by_email(cls, email):
        key = '<%s>' % email
        return cls.get_by_key_name(key)
    
class Company(db.Model):
    name = db.StringProperty()
    company_name = db.StringProperty()
    users = db.ListProperty(db.Key)
    admins = db.ListProperty(db.Key)
    
    @classmethod
    def get_by_user(cls, user, name=None):
        if not name:
            return Company.all().filter("admins = ", user.key()).fetch(1000)
        else:
            return Company.all().filter("admins = ", user.key()).filter('name = ', name).get()
        
    class Metadata:
        name = 'company'
        displa_name = u'Company'
        label = 'first_name'
        list = [('name', u'id'), 
                ('company_name', u'Compnay Name')]
        form = [('name', u'id'), 
                ('company_name', u'Compnay Name')]

class BaseModel(polymodel.PolyModel):
    created_time = db.DateTimeProperty(auto_now_add = True)
    created_by = db.UserProperty(auto_current_user_add = True)
    updated_time = db.DateTimeProperty(auto_now = True)
    updated_by = db.UserProperty(auto_current_user = True)
    company = db.ReferenceProperty(Company)

class Account(BaseModel):
    account_name = db.StringProperty()
    account_number = db.StringProperty()
    account_team = db.ListProperty(users.User)
    account_type = db.StringProperty()
    active = db.BooleanProperty(default=True)
    address = db.PostalAddressProperty()
    alias = db.StringProperty()
    annual_revenue = db.FloatProperty()
    category = db.StringProperty()
    description = db.StringProperty()
    employees = db.IntegerProperty()
    facebook_account = db.StringProperty()
    industry = db.StringProperty()
    language = db.StringProperty()
    location = db.StringProperty()
    logo_url = db.LinkProperty()
    main_phone = db.PhoneNumberProperty()
    main_fax = db.PhoneNumberProperty()
    note = db.TextProperty()
    parent_account = db.SelfReferenceProperty()
    rating = db.StringProperty()
    sic_code = db.StringProperty()
    stock_symbol =  db.StringProperty()
    twitter = db.StringProperty()
    website_url = db.LinkProperty()
    owner = db.UserProperty(auto_current_user_add = True)

class Contact(BaseModel):
    first_name = db.StringProperty()
    last_name = db.StringProperty()
    middle_name = db.StringProperty()
    alias_name = db.StringProperty()
    maiden_name = db.StringProperty()
    marital_status = db.StringProperty()
    suffix = db.StringProperty()
    prefix = db.StringProperty()
    display_name = db.StringProperty()
    nick_name = db.StringProperty()
    gender = db.StringProperty( choices=set(["M", "F"]))    
    birthday = db.DateProperty()
    nationality = db.StringProperty()
    note = db.TextProperty()
    profile_photo_url = db.LinkProperty()
    home_phone = db.PhoneNumberProperty()
    work_phone = db.PhoneNumberProperty()
    mobile_phone = db.PhoneNumberProperty()
    fax_phone = db.PhoneNumberProperty()
    other_phones = db.ListProperty(db.PhoneNumber)
    primary_email = db.EmailProperty()
    other_emails = db.ListProperty(db.Email)
    primary_IM = db.IMProperty()
    other_IMs = db.ListProperty(db.IM)
    primary_address = db.PostalAddressProperty()
    other_addresses = db.ListProperty(db.PostalAddress)
    tags = db.ListProperty(db.Category)
    language = db.StringProperty()
    locale = db.StringProperty()
    job_title = db.StringProperty()
    account = db.ReferenceProperty(Account)
    owner = db.UserProperty(auto_current_user_add = True)

    @classmethod
    def get_all_by_company(cls, company):
        return Contact.all().filter("company = ", company.key()).fetch(1000, 0)

        
class Task(BaseModel):
    task_number = db.StringProperty()
    account = db.ReferenceProperty(Account)
    alarm = db.BooleanProperty()
    category = db.StringProperty()
    comments = db.StringProperty()
    description = db.StringProperty()
    due = db.DateTimeProperty()
    employees = db.ListProperty(users.User)
    end = db.DateTimeProperty()
    new = db.BooleanProperty()
    priority = db.StringProperty()
    private = db.BooleanProperty()
    repeat_frequency = db.StringProperty()
    repeat_until = db.StringProperty()
    start = db.DateTimeProperty(auto_now_add = True)
    status = db.StringProperty()
    task_type =  db.StringProperty()
    owner = db.UserProperty(auto_current_user_add = True)
  
class Channel(db.Expando):
    company = db.ReferenceProperty(Company)
    name = db.StringProperty()
    channel_type = db.StringProperty()
    user_name = db.StringProperty()
    password = db.StringProperty()
    
    @classmethod
    def get_all_by_company(cls, company):
        return Channel.all().filter("company = ", company.key()).fetch(1000, 0)
    
class Campaign(db.Model):
    company = db.ReferenceProperty(Company)
    name = db.StringProperty()
    objective = db.StringProperty()
    status = db.StringProperty()
    campaign_type  = db.StringProperty()
    planned_start = db.DateTimeProperty()
    planned_end = db.DateTimeProperty()
    assigned_to = db.UserProperty
    description = db.StringProperty()
    summary = db.StringProperty()
    impressions = db.IntegerProperty()
    budget = db.FloatProperty()
    actual_expense = db.FloatProperty()
    forecast_revenue = db.FloatProperty()
    actual_revenue = db.FloatProperty()
    forecast_units = db.IntegerProperty()
    actual_units = db.IntegerProperty()
      
    @classmethod
    def get_all_by_company(cls, company):
        return Campaign.all().filter("company = ", company.key()).fetch(1000, 0)

class Message(BaseModel):
    name = db.StringProperty()
    message_from = db.StringProperty()
    message_to = db.StringProperty()
    subject = db.StringProperty()
    content = db.TextProperty()
    message_type = db.StringProperty()
    tag = db.StringProperty()

class CampaignMessage(Message):
    message_code = db.StringProperty()
    channel = db.ReferenceProperty(Channel)
    activatiion_date = db.DateTimeProperty()
    description = db.StringProperty()
    landing_url = db.StringProperty()
    short_url = db.StringProperty()
    impressions = db.IntegerProperty()
    template_name = db.StringProperty()
    campaign = db.ReferenceProperty(Campaign)

    @classmethod
    def get_all_by_campaign(cls, campaign):
        return CampaignMessage.all().filter("campaign = ", campaign.key()).fetch(1000, 0)

    
class TrackerURL(db.Model):
    campaign = db.ReferenceProperty(Campaign)
    tracker_id = db.StringProperty()
    clicks = db.FloatProperty(default=0)
    
class ResponseBehaivor(db.Model):
    sesssion = db.StringProperty()
    message = db.ReferenceProperty(CampaignMessage)
    click_1 = db.ReferenceProperty(TrackerURL, collection_name="click_1_set")
    click_2 = db.ReferenceProperty(TrackerURL, collection_name="click_2_set")
    click_3 = db.ReferenceProperty(TrackerURL, collection_name="click_3_set")
    click_4 = db.ReferenceProperty(TrackerURL, collection_name="click_4_set")
    click_5 = db.ReferenceProperty(TrackerURL, collection_name="click_5_set")
    
